#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <stdlib.h>
#include <syslog.h>

/* create two process group
 * add two process to PG1,(p1, p2)
 * add one process to PG2,(p3)
 * then move the first process of PG1 to PG2
 */

void p1_sig(int signo)
{
	printf("process(%d) receive %d signal\n", getpid(), signo);
	syslog(LOG_USER | LOG_PID | LOG_INFO, "p1_sig(%m)");
	signal(SIGUSR1, p1_sig);
}

void p3_sig(int signo)
{
	fprintf(stderr, "process(%d) receive %d signal\n", getpid(), signo);
	syslog(LOG_USER | LOG_PID | LOG_INFO, "p3_sig(%m)");

	signal(SIGUSR1, p3_sig);
}

int main(void)
{
	pid_t p1;
	pid_t p2;
	pid_t p3;
	pid_t pg1;
	pid_t pg2;

	p1 = fork();
	if (p1 == 0)
	{
		/* child */
		int c = 0;

		if (signal(SIGUSR1, p1_sig) == SIG_ERR)
		{
			printf("signal error: %s\n", strerror(errno));

			return 1;
		}
		printf("p1 sid = %d\n", getsid(0));
		sleep(5);

		exit(1);
	}


	p2 = fork();
	if (p2 == 0)
	{
		int c = 0;

		if (signal(SIGUSR1, p1_sig) == SIG_ERR)
		{
			printf("signal error: %s\n", strerror(errno));

			return 1;
		}
		printf("p2 sid = %d\n", getsid(0));
		sleep(5);

		exit(2);
	}

	if (setpgid(p1, p1) < 0)
	{
		printf("setpgid error: %s\n", strerror(errno));

		return 1;
	}
	
	pg1 = p1;
	if (setpgid(p2, pg1) < 0)
	{
		printf("setpgid error: %s\n", strerror(errno));
		return 2;
	}

	p3 = fork();
	if (p3 == 0)
	{
		/* child */
		int c = 0;

		if (signal(SIGUSR1, p3_sig) == SIG_ERR)
		{
			printf("signal error: %s\n", strerror(errno));

			return 1;
		}

		printf("p3 sid = %d\n", getsid(0));
		sleep(5);

		exit(3);
	}

	printf("p1 = %d, p2 = %d, p3 = %d\n", p1, p2, p3);
	printf("SIGUSR1 = %d \n", SIGUSR1);

	if (setpgid(p3, p3) < 0)
	{
		printf("setpgid error: %s\n", strerror(errno));
		return 2;
	}

	pg2 = p3;
	printf("pg1 = %d, pg2 = %d\n", pg1, pg2);

#if 0
	/* move p1 from PG1 to PG2 */
	if (setpgid(p1, pg2) < 0)
	{
		printf("setpgid error: %s\n", strerror(errno));
		return 3;
	}
#endif	

	sleep(3);
#if 1
	if (killpg(pg2, SIGUSR1) < 0)
	{
		printf("kill error: %s\n", strerror(errno));
	}

#endif
	exit(0);
}


